package com.webank.maling.rule.config;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.yaml.snakeyaml.Yaml;

import java.io.InputStream;
import java.util.List;
import java.util.Map;

/**
 * 规则配置管理
 */
@Slf4j
@Data
public class RuleConfiguration {
    
    private static final RuleConfiguration INSTANCE = new RuleConfiguration();
    
    /**
     * 入口点规则配置
     */
    private EntryPointRules entryPointRules;
    
    /**
     * 依赖注入规则配置（预留扩展）
     */
    private DependencyInjectionRules dependencyInjectionRules;
    
    /**
     * RPC规则配置（预留扩展）
     */
    private RpcRules rpcRules;
    
    private RuleConfiguration() {
        loadConfiguration();
    }
    
    public static RuleConfiguration getInstance() {
        return INSTANCE;
    }
    
    /**
     * 加载配置文件
     */
    private void loadConfiguration() {
        try (InputStream input = getClass().getClassLoader().getResourceAsStream("rules/rules.yml")) {
            if (input == null) {
                log.warn("Rules configuration file not found, using default rules");
                loadDefaultRules();
                return;
            }
            
            Yaml yaml = new Yaml();
            Map<String, Object> config = yaml.load(input);
            
            // 加载入口点规则
            if (config.containsKey("entryPointRules")) {
                @SuppressWarnings("unchecked")
                Map<String, Object> entryPointConfig = (Map<String, Object>) config.get("entryPointRules");
                this.entryPointRules = parseEntryPointRules(entryPointConfig);
            }
            
            log.info("Rules configuration loaded successfully");
        } catch (Exception e) {
            log.error("Failed to load rules configuration, using default rules", e);
            loadDefaultRules();
        }
    }
    
    /**
     * 解析入口点规则配置
     */
    @SuppressWarnings("unchecked")
    private EntryPointRules parseEntryPointRules(Map<String, Object> config) {
        EntryPointRules rules = new EntryPointRules();
        
        if (config.containsKey("enabled")) {
            rules.setEnabled((Boolean) config.get("enabled"));
        }
        
        if (config.containsKey("rules")) {
            rules.setRules((List<String>) config.get("rules"));
        }
        
        if (config.containsKey("customFunctions")) {
            rules.setCustomFunctions((Map<String, String>) config.get("customFunctions"));
        }
        
        return rules;
    }
    
    /**
     * 加载默认规则
     */
    private void loadDefaultRules() {
        this.entryPointRules = new EntryPointRules();
        this.entryPointRules.setEnabled(true);
        this.entryPointRules.setRules(List.of(
            "hasAnnotation('org.springframework.web.bind.annotation.RequestMapping')",
            "hasAnnotation('org.springframework.web.bind.annotation.GetMapping')",
            "hasAnnotation('org.springframework.web.bind.annotation.PostMapping')",
            "hasAnnotation('org.springframework.web.bind.annotation.PutMapping')",
            "hasAnnotation('org.springframework.web.bind.annotation.DeleteMapping')",
            "hasAnnotation('org.springframework.web.bind.annotation.PatchMapping')",
            "implementsInterface('org.springframework.web.servlet.mvc.Controller')",
            "implementsInterface('javax.servlet.http.HttpServlet') and methodName == 'doGet'",
            "implementsInterface('javax.servlet.http.HttpServlet') and methodName == 'doPost'"
        ));
    }
    
    /**
     * 入口点规则配置
     */
    @Data
    public static class EntryPointRules {
        private Boolean enabled = true;
        private List<String> rules;
        private Map<String, String> customFunctions;
    }
    
    /**
     * 依赖注入规则配置（预留扩展）
     */
    @Data
    public static class DependencyInjectionRules {
        private Boolean enabled = false;
        private List<String> rules;
    }
    
    /**
     * RPC规则配置（预留扩展）
     */
    @Data
    public static class RpcRules {
        private Boolean enabled = false;
        private List<String> rules;
    }
}
